package xyz.syyrjx.registry.handler;

import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import xyz.syyrjx.entity.SyyrjxRpcRemoteAddress;
import xyz.syyrjx.registry.task.SyyrjxRpcRegistrySynchronizeTask;
import xyz.syyrjx.request.*;
import xyz.syyrjx.response.SyyrjxRpcResponse;
import xyz.syyrjx.code.SyyrjxRpcCoder;
import xyz.syyrjx.exception.SyyrjxRpcRegistryException;
import xyz.syyrjx.registry.constant.SyyrjxRpcProviderRegistryTable;

import java.util.Map;
import java.util.Set;

/**
 * @author 大地崩坏苍蝇兽
 * @date 2023/1/11 - 14:35
 */
@ChannelHandler.Sharable
public class SyyrjxRpcRegistryServerHandler extends SimpleChannelInboundHandler<String> {

    private final static Logger LOGGER = LoggerFactory.getLogger(SyyrjxRpcRegistryServerHandler.class);

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String str) throws Exception {
        SyyrjxRpcRequest request = SyyrjxRpcCoder.StringToObject(str);
        LOGGER.debug("接收" + ctx.channel().remoteAddress() + "的到请求:" + request);

        if (request == null) {
            ctx.writeAndFlush(SyyrjxRpcResponse.registryFail(SyyrjxRpcRegistryException.REGISTRY_CENTER_ERROR).toSerializableString());
            return;
        }
        LOGGER.debug(request.toString());

        if (request instanceof SyyrjxRpcRegistryRequest) {
            LOGGER.debug("收到提供者注册地址请求");

            SyyrjxRpcRegistryRequest registryRequest = (SyyrjxRpcRegistryRequest) request;
            if (!registryRequest.isFromRegistryCenter()) {
                registryRequest.setFromRegistryCenter(true);
                SyyrjxRpcRegistrySynchronizeTask.run(registryRequest);
            }

            String[] providerNames = registryRequest.getProviderNames();
            SyyrjxRpcRemoteAddress address = registryRequest.getAddress();
            registry(providerNames, address);
            LOGGER.debug("注册结束");
            ctx.writeAndFlush(SyyrjxRpcResponse.success("").toSerializableString());

        } else if (request instanceof SyyrjxRpcGetAddressRequest) {
            LOGGER.debug("收到消费者获取地址集合请求");
            SyyrjxRpcGetAddressRequest getAddressRequest = (SyyrjxRpcGetAddressRequest) request;
            Set<SyyrjxRpcRemoteAddress> set = call(getAddressRequest);
            LOGGER.debug("获取到地址集合" + set);
            SyyrjxRpcResponse response = SyyrjxRpcResponse.success(set);
            response.setFutureId((getAddressRequest.getFutureId()));
            ctx.writeAndFlush(response.toSerializableString());
            LOGGER.debug("注册中心成功返回信息");

        }else if (request instanceof SyyrjxRpcRegistrySynchronizeRequest) {
            LOGGER.debug("接收到其它注册中心" + ctx.channel().remoteAddress() + "同步请求");
            SyyrjxRpcRegistrySynchronizeRequest synchronizeRequest = (SyyrjxRpcRegistrySynchronizeRequest) request;

            //完成同步
            Map<String, Set<SyyrjxRpcRemoteAddress>> providerAddressMap = synchronizeRequest.getProviderAddressMap();
            if (providerAddressMap.size() > 0) {
                SyyrjxRpcProviderRegistryTable.synchronize(providerAddressMap);
            }

        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.writeAndFlush(SyyrjxRpcResponse.registryFail(SyyrjxRpcRegistryException.REGISTRY_CENTER_ERROR).toSerializableString());
        LOGGER.error(cause.getMessage() + ctx.channel().remoteAddress());
    }


    public void registry(String[] providerNames, SyyrjxRpcRemoteAddress address) {
            SyyrjxRpcProviderRegistryTable.registry(providerNames, address);
    }

    public Set<SyyrjxRpcRemoteAddress> call(SyyrjxRpcGetAddressRequest request) {
        String providerName = request.getProviderName();
        return SyyrjxRpcProviderRegistryTable.call(providerName);
    }
}
